<?php
/**
 * Created by PhpStorm.
 * User: bzg
 * Date: 2019/12/6
 * Time: 9:43
 */

namespace App\Extend\SysExtend\File\Driver;


use App\Common\Exception\ServiceRunTimeException;
use App\Extend\SysExtend\File\FileAbstract;
use App\Extend\SysExtend\Helper;
use EasySwoole\EasySwoole\Config;

class FileLocal extends FileAbstract
{

    /**
     * 获取资源路径
     * @param string $name 路径
     * @return string
     * @throws \Throwable
     */
    public function get(string $name): string
    {
        // TODO: Implement get() method.
        if(!empty($name))
        {
            if(strpos($name, 'http') === false)
            {
                $host = Config::getInstance()->getConf('WEB_URL');
                $dir = Helper::config('extend.resource_dir');
                $name =  ($dir ? $dir : '') . '/' . $name;
                return $host . '/' . $name;
            }
            return $name;
        }
        return '';
    }


    /**
     * 删除资源对象
     * @param string $name 文件名或者路径
     * @return bool
     * @throws \Throwable
     */
    public function delete(string $name): bool
    {
        // TODO: Implement delete() method.
        // 尝试删除原图
        try{
            $old_path = EASYSWOOLE_ROOT . '/Public/' . (Helper::config('extend.resource_dir') ?? '') . '/' . $name;
            $old_path = str_replace('//','/', $old_path);
            if(file_exists($old_path)) unlink($old_path);
            return true;
        }catch (\Exception $e) {
            return false;
        }
    }


    /**
     * 上传二进制文件
     * @param string|array $file_info  文件上传信息（字符串为文件名。数组则第一元素为名字，第二元素为验证条件）
     * @param string       $path       文件上传路径
     * @return string
     * @throws ServiceRunTimeException
     * @throws \Throwable
     */
    public function uploadBin($file_info, $path)
    {
        // file_info 为数组则第一元素为名字，第二元素为验证条件
        $name = $file_info;
        $validate = [];
        if(is_array($file_info)) {
            $name = $file_info[0];
            $validate = $file_info[1];
        }

        $file = Helper::request()->getUploadedFile($name);
        if(!$file) {
            throw new ServiceRunTimeException('没有上传文件' . $name);
        }

        // 验证大小
        $size = (empty($validate['size']) ? 2 : $validate['size']) * 1024 * 1024;
        if($file->getSize() > $size) {
            throw new ServiceRunTimeException('文件大小超过限制');
        }
        // 校验宽高
        if(!empty($validate['width']) || !empty($validate['height'])) {
            $img_size = getimagesize($file->getTempName());
            // 校验宽度
            if(!empty($validate['width']) && $img_size[0] > $validate['width']) {
                $re = $this->checkHW($validate['width'],$img_size[0]);
                if(!$re['re'])
                    throw new ServiceRunTimeException('图片宽度应'.$re['msg'].$re['size'].'px');
            }
            // 校验高度
            if(!empty($validate['height']) && $img_size[0] > $validate['height']) {
                $re = $this->checkHW($validate['height'],$img_size[0]);
                if(!$re['re'])
                    throw new ServiceRunTimeException('图片高度应'.$re['msg'].$re['size'].'px');
            }
        }
        // 类型转换数组
        $file_types = [
            'image/gif' => 'gif',
            'image/jpeg' => 'jpeg',
            'image/jpg' => 'jpg',
            'image/pjpeg' => 'jpg',
            'image/png' => 'png',
            'image/x-png' => 'png',
            'image/bmp' => 'bmp',
            'application/octet-stream' => 'rar',
            'application/zip' => 'zip',
            'audio/mpeg' => 'mp3',
            'video/mp4' => 'mp4'
        ];
        // 校验类型
        if(!empty($validate['ext']) && !in_array($file_types[$file->getClientMediaType()],$validate['ext'])) {
            throw new ServiceRunTimeException('文件类型错误');
        }
        // 生成路径
        $save_path = $this->savePath($path);

        // 生成文件名
        $file_name = uniqid() . time() . mt_rand(1000,9999) . '.' .$file_types[$file->getClientMediaType()];
        $re = $file->moveTo($save_path['path'] . $file_name);
        if($re){
            // 输出 20160820/42a79759f284b767dfcb2a0197904287.jpg
            return $save_path['dir'] . $file_name;
        }else{
            throw new ServiceRunTimeException('文件上传失败');
        }
    }


    /**
     * 上传base64
     * @param string|array $file_info
     * @param string $path
     * @return mixed|string
     * @throws ServiceRunTimeException
     */
    public function uploadBase64($file_info, $path)
    {

        $base64 = $file_info;
        $validate = [];
        if(is_array($file_info)) {
            $base64 = $file_info[0];
            $validate = $file_info[1];
        }
        if (strpos($base64, 'https://') !== false || strpos($base64, 'http://') !== false) {// 没有上传新图
            return $base64;
        }
        // 校验文件
        $type = $this->checkBase64($base64,$validate);

        $save_path = $this->savePath($path);

        $filename = uniqid() . time() . rand(1000, 9999) . ".{$type}";
        $base64 = explode(';base64,', $base64)[1];

        if (file_put_contents($save_path['path'] . $filename, base64_decode($base64))) {
            return  $save_path['dir'] . $filename;
        } else {
            throw new ServiceRunTimeException('文件上传失败');
        }
    }

    // 获取储存路径
    private function savePath(string $path)
    {
        $dir = $path ? $path : date('Ymd') . '/';
        $path = EASYSWOOLE_ROOT . '/Public/' . (Helper::config('extend.resource_dir') ?? '') . '/' . $dir;
        if(!is_dir($path)) {
            mkdir($path,0777,true);
        }
        return ['path'=>$path,'dir'=>$dir];
    }
}